﻿using System;
using System.Diagnostics.Contracts;
using System.Threading;

namespace Ping.Server.Cron
{
	/// <summary>
	/// A cron-job, ie. a task that runs in predefined intervals.
	/// </summary>
	public sealed class CronJob
	{
		/// <summary>
		/// The interval at which the cron-job whishes to be performed.
		/// </summary>
		public readonly TimeSpan Interval;

		/// <summary>
		/// The name of this cron-job.
		/// </summary>
		public readonly string Name;

		private readonly Action _job;
		private Timer _timer;

		public CronJob(string name, TimeSpan interval, Action job)
		{
			if (name == null || job == null)
				throw new ArgumentNullException();
			if (interval <= TimeSpan.Zero)
				throw new ArgumentException("A cronjob requires a positive non-zero interval between invocations");

			Name = name;
			Interval = interval;
			_job = job;
		}

		public void Start()
		{
			if (_timer != null)
				throw new InvalidOperationException();

			_timer = new Timer(Perform, null, TimeSpan.Zero, Interval);
		}

		public void Stop()
		{
			if (_timer == null)
				throw new InvalidOperationException();

			_timer.Dispose();
			_timer = null;
		}

		/// <summary>
		/// Performs the cron-job.
		/// </summary>
		private void Perform(object state)
		{
			_job();
		}
	}
}